﻿namespace Rio.Manager.Application.ViewModel.FolderTypeAdministration
{
    using System;
    using System.Collections.ObjectModel;
    using System.Linq;
    using System.ServiceModel.DomainServices.Client;
    using System.Windows.Controls;

    using GalaSoft.MvvmLight.Command;
    using GalaSoft.MvvmLight.Messaging;

    using NetBay.Core.BusinessEntities;
    using NetBay.Core.BusinessEntities.Workflow;

    using Rio.Applications.Web.Services;
    using Rio.Framework.Localisation;
    using Rio.Framework.Pages;
    using Rio.Framework.Pages.Context;
    using Rio.Manager.Application.ViewModel.BaseClass;
    using Rio.Manager.Application.ViewModel.Locator;
    using Rio.Framework.Pages.Controls;
    using Rio.Framework.Pages.ChildWindows;

    public class ManageWorkflowTabViewModel : TabViewModelBase
    {
        #region Fields

        private string _DeleteWorkflowText;
        private string _EditWorkflowText;
        private string _NewChildWorkflowText;
        private string _NewWorkflowText;
        private string _RefreshWorkflowText;
        private WorkflowDefinition _selectedWorkflow;
        private ObservableCollection<WorkflowDefinition> _workflowDefinitions;
        private ObservableCollection<WorkflowDefinition> _workflowParentDefinitions;
        private string _WorkflowDefinitionsGridView_Description;
        private string _WorkflowDefinitionsGridView_EndDate;
        private string _WorkflowDefinitionsGridView_Name;
        private string _WorkflowDefinitionsGridView_StartDate;
        private string _WorkflowListText;



        #endregion Fields

        #region Constructors

        /// <summary>
        /// Initializes a new instance of the <see cref="ManageWorkflowTabViewModel"/> class.
        /// </summary>
        public ManageWorkflowTabViewModel()
            : base()
        {
            CanCloseTab = true;
            TabIcon = new Uri("/Rio.Manager.Application;component/Assets/Images/manageworkflow.png", UriKind.Relative);
        }

        #endregion Constructors

        #region Properties

        public RelayCommand CreateChildWorkflowCommand
        {
            get;
            set;
        }

        public RelayCommand CreateNewWorkflowCommand
        {
            get;
            set;
        }

        public RelayCommand DeleteWorkflowCommand
        {
            get;
            set;
        }

        public string DeleteWorkflowText
        {
            get { return _DeleteWorkflowText; }
            set
            {
                _DeleteWorkflowText = value;
                RaisePropertyChanged("DeleteWorkflowText");
            }
        }

        public RelayCommand EditWorkflowCommand
        {
            get;
            set;
        }

        public string EditWorkflowText
        {
            get { return _EditWorkflowText; }
            set
            {
                _EditWorkflowText = value;
                RaisePropertyChanged("EditWorkflowText");
            }
        }

        public RelayCommand InitializationCommand
        {
            get;
            set;
        }

        public string NewChildWorkflowText
        {
            get { return _NewChildWorkflowText; }
            set
            {
                _NewChildWorkflowText = value;
                RaisePropertyChanged("NewChildWorkflowText");
            }
        }

        public string NewWorkflowText
        {
            get { return _NewWorkflowText; }
            set
            {
                _NewWorkflowText = value;
                RaisePropertyChanged("NewWorkflowText");
            }
        }

        public RelayCommand RefreshCommand
        {
            get;
            set;
        }

        public string RefreshWorkflowText
        {
            get { return _RefreshWorkflowText; }
            set
            {
                _RefreshWorkflowText = value;
                RaisePropertyChanged("RefreshWorkflowText");
            }
        }

        public override FolderType SelectedFolderType
        {
            get
            {
                return base.SelectedFolderType;
            }
            set
            {
                base.SelectedFolderType = value;
                RaisePropertyChanged("SelectedFolderType");

                LoadOrRefreshWorkflowList();

                RefreshCommand.RaiseCanExecuteChanged();
            }
        }

        public WorkflowDefinition SelectedWorkflow
        {
            get { return _selectedWorkflow; }
            set
            {
                _selectedWorkflow = value;

                RaisePropertyChanged("SelectedWorkflow");

                EditWorkflowCommand.RaiseCanExecuteChanged();
                CreateChildWorkflowCommand.RaiseCanExecuteChanged();
                DeleteWorkflowCommand.RaiseCanExecuteChanged();
            }
        }

        public ObservableCollection<WorkflowDefinition> WorkflowDefinitions
        {
            get { return _workflowDefinitions; }
            set
            {
                _workflowDefinitions = value;
                RaisePropertyChanged("WorkflowDefinitions");
            }
        }

        public ObservableCollection<WorkflowDefinition> WorkflowParentDefinitions
        {
            get { return _workflowParentDefinitions; }
            set
            {
                _workflowParentDefinitions = value;
                RaisePropertyChanged("WorkflowParentDefinitions");
            }
        }

        public string WorkflowDefinitionsGridView_Description
        {
            get { return _WorkflowDefinitionsGridView_Description; }
            set
            {
                _WorkflowDefinitionsGridView_Description = value;
                RaisePropertyChanged("WorkflowDefinitionsGridView_Description");
            }
        }

        public string WorkflowDefinitionsGridView_EndDate
        {
            get { return _WorkflowDefinitionsGridView_EndDate; }
            set
            {
                _WorkflowDefinitionsGridView_EndDate = value;
                RaisePropertyChanged("WorkflowDefinitionsGridView_EndDate");
            }
        }

        public string WorkflowDefinitionsGridView_Name
        {
            get { return _WorkflowDefinitionsGridView_Name; }
            set
            {
                _WorkflowDefinitionsGridView_Name = value;
                RaisePropertyChanged("WorkflowDefinitionsGridView_Name");
            }
        }

        public string WorkflowDefinitionsGridView_StartDate
        {
            get { return _WorkflowDefinitionsGridView_StartDate; }
            set
            {
                _WorkflowDefinitionsGridView_StartDate = value;
                RaisePropertyChanged("WorkflowDefinitionsGridView_StartDate");
            }
        }

        public string WorkflowListText
        {
            get { return _WorkflowListText; }
            set
            {
                _WorkflowListText = value;
                RaisePropertyChanged("WorkflowListText");
            }
        }

        #endregion Properties

        #region Methods

        /// <summary>
        /// Creates the new workfow.
        /// </summary>
        public void CreateChildWorkflow()
        {
            NewWorkflowTabViewModel newTab = ViewModelLocator.NewChildflowTabViewModelStatic;

            newTab.IsEdited = false;
            newTab.IsChildCreation = true;
            newTab.SelectedOrganization = SelectedOrganization;
            newTab.SelectedFolderType = SelectedFolderType;
            newTab.ParentWorkflowDefinition = SelectedWorkflow;

            AddTab(newTab);
        }

        /// <summary>
        /// Creates the new workfow.
        /// </summary>
        public void CreateNewWorkflow()
        {
            TabViewModelBase newTab = ViewModelLocator.NewWorkflowTabViewModelStatic;

            newTab.SelectedOrganization = SelectedOrganization;
            newTab.SelectedFolderType = SelectedFolderType;

            AddTab(newTab);
        }

        /// <summary>
        /// Inits the commands.
        /// </summary>
        public override void InitCommands()
        {
            InitializationCommand = new RelayCommand(Initialization);

            CreateNewWorkflowCommand = new RelayCommand(CreateNewWorkflow);

            CreateChildWorkflowCommand = new RelayCommand(
                CreateChildWorkflow,
                () => SelectedWorkflow != null);

            EditWorkflowCommand = new RelayCommand(
                EditWorkflow,
                () => SelectedWorkflow != null);

            DeleteWorkflowCommand = new RelayCommand(
                DeleteWorkflow,
                () => SelectedWorkflow != null);

            RefreshCommand = new RelayCommand(LoadWorkflowDefinitions, () => SelectedFolderType != null);
        }

        /// <summary>
        /// Inits the labels.
        /// </summary>
        public override void InitLabels()
        {
            TabTitle = Resx.GetLabel(ResxRioManager.MANAGE_WORFKLOW);

            WorkflowListText = Resx.GetLabel(ResxRioManager.MANAGEWORKFLOWTABVIEWMODEL_WORKFLOWLISTTEXT);
            NewWorkflowText = Resx.GetLabel(ResxRioManager.MANAGEWORKFLOWTABVIEWMODEL_NEWWORKFLOWTEXT);
            NewChildWorkflowText = Resx.GetLabel(ResxRioManager.MANAGEWORKFLOWTABVIEWMODEL_NEWCHILDWORKFLOWTEXT);
            EditWorkflowText = Resx.GetLabel(ResxRioManager.MANAGEWORKFLOWTABVIEWMODEL_EDITWORKFLOWTEXT);
            DeleteWorkflowText = Resx.GetLabel(ResxRioManager.MANAGEWORKFLOWTABVIEWMODEL_DEACTIVATEWORKFLOWTEXT);
            RefreshWorkflowText = Resx.GetLabel(ResxRioManager.MANAGEWORKFLOWTABVIEWMODEL_REFRESHWORKFLOWTEXT);
            WorkflowDefinitionsGridView_Name = Resx.GetLabel(ResxRioManager.MANAGEWORKFLOWTABVIEWMODEL_WORKFLOWDEFINITIONSGRIDVIEW_NAME);
            WorkflowDefinitionsGridView_Description = Resx.GetLabel(ResxRioManager.MANAGEWORKFLOWTABVIEWMODEL_WORKFLOWDEFINITIONSGRIDVIEW_DESCRIPTION);
            WorkflowDefinitionsGridView_StartDate = Resx.GetLabel(ResxRioManager.MANAGEWORKFLOWTABVIEWMODEL_WORKFLOWDEFINITIONSGRIDVIEW_STARTDATE);
            WorkflowDefinitionsGridView_EndDate = Resx.GetLabel(ResxRioManager.MANAGEWORKFLOWTABVIEWMODEL_WORKFLOWDEFINITIONSGRIDVIEW_ENDDATE);
        }

        /// <summary>
        /// Refreshes the workflow list.
        /// </summary>
        public void LoadOrRefreshWorkflowList(NotificationMessage msg = null)
        {
            LoadWorkflowDefinitions();
        }

        /// <summary>
        /// Deletes the workflow.
        /// </summary>
        private void DeleteWorkflow()
        {
            //Show popup to deactivate the definition
            DateTimePickerChildWindow dateTimePickerChildWindow = new DateTimePickerChildWindow()
            {
                DescriptionText = Resx.GetLabel(ResxRioManager.WORKFLOWDEFINITION_DEACTIVATE_CONFIRMATION),
                DateTimePickerText = Resx.GetLabel(ResxRioManager.MANAGEWORKFLOWTABVIEWMODEL_DEACTIVATEDATEWORKFLOWTEXT) + " :",
                SelectedDateTime = DateTime.Now
            };

            dateTimePickerChildWindow.Closed += (s, e) =>
            {
                if (((DateTimePickerChildWindow)s).DialogResult == true)
                {
                    DeactivateDefintion(SelectedWorkflow, ((DateTimePickerChildWindow)s).SelectedDateTime);
                }
            };

            dateTimePickerChildWindow.ShowDialog();
        }

        /// <summary>
        /// Deactivates the defintion.
        /// </summary>
        /// <param name="wkfDefinition">The WKF definition.</param>
        /// <param name="deactivatedDate">The deactivated date.</param>
        private void DeactivateDefintion(WorkflowDefinition wkfDefinition, DateTime deactivatedDate)
        {
            BusyIndicator.Clear();
            BusyIndicator.AddBusyTask();

            //Deactivate the definition to the specified date
            BusinessEntitiesDomainContext businessEntitiesDomainContext = GlobalWebContext.BusinessEntitiesDomainContext;
            businessEntitiesDomainContext.DeactivateDefinition(
                wkfDefinition.Identifier, deactivatedDate,
                (retr) =>
                {
                    BusyIndicator.RemoveBusyTask();

                    if (retr.HasError || !retr.Value.Value)
                    {
                        ShowModalDialog(
                            Resx.GetLabel(ResxCommon.ERROR),
                            Resx.GetLabel(ResxRioManager.WORKFLOWDEFINITION_DELETE_ERROR),
                            MessageBoxButtons.Ok,
                            MessageBoxIcon.Error);
                    }
                    else
                    {
                        ShowModalDialog(
                            String.Empty,
                            Resx.GetLabel(ResxRioManager.WORKFLOWDEFINITION_DELETE_SUCCESS),
                            MessageBoxButtons.Ok,
                            MessageBoxIcon.Information);
                    }

                    LoadOrRefreshWorkflowList();
                },
                null);
        }

        /// <summary>
        /// Edits the workflow.
        /// </summary>
        private void EditWorkflow()
        {
            NewWorkflowTabViewModel newWorkflowTabViewModel = ViewModelLocator.NewWorkflowTabViewModelStatic;

            Action<TabViewModelBase> action = (tab =>
                                                    {
                                                        newWorkflowTabViewModel.SelectedOrganization = SelectedOrganization;
                                                        newWorkflowTabViewModel.SelectedFolderType = SelectedFolderType;
                                                        LoadChildren(SelectedWorkflow);
                                                        newWorkflowTabViewModel.SetEditMode(SelectedWorkflow);
                                                        newWorkflowTabViewModel.SelectedRecipientIndex = new Index { Indentifier = Convert.ToInt64(SelectedWorkflow.ReceiverIndexId) };
                                                        newWorkflowTabViewModel.Groups = SelectedWorkflow.ReceiverGroupId == null ? null : SelectedWorkflow.ReceiverGroupId.Select(i => new Group() { Identifier = i }).ToList();
                                                    });

            AddTab(newWorkflowTabViewModel, action);
        }

        /// <summary>
        /// Initializations this instance.
        /// </summary>
        private void Initialization()
        {
            InitLabels();

            EditWorkflowCommand.RaiseCanExecuteChanged();
            DeleteWorkflowCommand.RaiseCanExecuteChanged();
            RefreshCommand.RaiseCanExecuteChanged();

            Messenger.Default.Register<NotificationMessage>(this, LoadOrRefreshWorkflowList);
        }

        /// <summary>
        /// Loads the workflow definitions.
        /// </summary>
        private void LoadWorkflowDefinitions()
        {
            if (SelectedFolderType != null)
            {
                BusyIndicator.Clear();
                BusyIndicator.AddBusyTask();

                BusinessEntitiesDomainContext businessEntitiesDomainContext = GlobalWebContext.BusinessEntitiesDomainContext;
                var query = businessEntitiesDomainContext.GetWorkflowDefinitionsByFolderTypeIdQuery(SelectedFolderType.Identifier);

                businessEntitiesDomainContext.Load(
                    query,
                    delegate(LoadOperation<WorkflowDefinition> retr)
                    {
                        BusyIndicator.RemoveBusyTask();

                        if (!retr.HasError && retr.Entities != null)
                        {

                            WorkflowDefinitions = new ObservableCollection<WorkflowDefinition>(retr.Entities);

                            WorkflowParentDefinitions = new ObservableCollection<WorkflowDefinition>(retr.Entities.Where(p => p.ParentId == null));
                        }
                    },
                    null);
            }
        }

        /// <summary>
        /// Loads the children.
        /// </summary>
        /// <param name="definition">The definition.</param>
        public void LoadChildren(WorkflowDefinition definition)
        {
            var childs = WorkflowDefinitions.Where(p => p.ParentId == definition.Identifier).ToList();
            foreach (var item in childs)
            {
                definition.Childs.Add(item);
            }
        }

        #endregion Methods
    }
}